using System;
using System.Diagnostics;

namespace GraphEditor.Runtime
{

    /// <summary>
    /// 图容器标记特性，被标记的类就相当于是一个逻辑图容器类。没有这个特性的话，就没法做查找。
    /// </summary>
    [Conditional("UNITY_EDITOR")]
    [AttributeUsage(AttributeTargets.Class)]
    public class GraphAttribute : Attribute
    {
        /// <summary>
        /// 当前Graph的逻辑节点基类
        /// </summary>
        public Type BaseNodeType { get; }
        /// <summary>
        /// 当前Graph的逻辑连线基类
        /// </summary>
        public Type BaseEdgeType { get; }
    }

    /// <summary>
    /// 节点标记特性，被标记的类就相当于是一个逻辑节点类。需要这个特性来查找。
    /// 如果标记的是字段，那么这个字段就会被当作一个烘焙接收器，表示它应该接收烘焙后的节点列表。
    /// </summary>
    [Conditional("UNITY_EDITOR")]
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field)]
    public class NodeAttribute : Attribute
    {
    }

    /// <summary>
    /// 连线标记特性。被标记的类就相当于是一个逻辑连线类。需要这个特性来查找。
    /// 如果标记的是字段，那么这个字段就会被当作一个烘焙接收器，表示它应该接收烘焙后的连线列表。
    /// </summary>
    [Conditional("UNITY_EDITOR")]
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field)]
    public class EdgeAttribute : Attribute
    {
    }

    /// <summary>
    /// 端口标记特性。因为端口本身没有类的特性，一般存在于节点之中，所以这里相当于是一个逻辑端口类。比如被标记的节点里存在某个参数，或者某个List，可以被标记为端口。允许一个字段有多个端口特性。
    /// </summary>
    [Conditional("UNITY_EDITOR")]
    [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
    public class PortAttribute : Attribute
    {
        // 1. 端口方向 (必须)
        public PortDirection Direction { get; }

        // 2. 连接容量 (可选, 默认单连接)
        // PortCapacity.Single: 只能连一根线 (如行为树的父节点)
        // PortCapacity.Multiple: 可以连多根线 (如状态机的输入、节点的子节点列表)
        public PortCapacity Capacity { get; set; } = PortCapacity.Single;

        // 3. (可选) 端口名称
        // 如果不指定，就用字段名。如果一个字段有多个端口，则必须指定。
        public string Name { get; set; }

        // 4. (可选) 端口类型分组，用于连接校验
        // 例如，你可以定义 "Execution", "FloatData", "GameObjectData"
        // 默认情况下，只有相同类型的端口才能连接
        public string Type { get; set; } = "Default";

        public PortAttribute(PortDirection direction)
        {
            Direction = direction;
        }
    }

    /// <summary>
    /// 端口方向
    /// </summary>
    public enum PortDirection { Input, Output }
    /// <summary>
    /// 端口连接容量
    /// </summary>
    public enum PortCapacity { Single, Multiple }
}